package lock;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;

/**
 * redis 单机锁
 *
 * @Author: ShenWei
 * @Date: 2024/06/20/9:01
 */
public class AloneLock implements Lock {

    // 维护一个原子对象,内部是Thread
    AtomicReference<Thread> owner = new AtomicReference<>();

    // 维护一个阻塞队列
    LinkedBlockingQueue<Thread> waiter = new LinkedBlockingQueue<>();

    /**
     * 加锁
     */
    @Override
    public void lock() {
        // 判断当前线程是否能进入原子对象
        while (!owner.compareAndSet(null, Thread.currentThread())) {
            // 如果不能进入
            // 就进入阻塞队列
            waiter.add(Thread.currentThread());
            // 并且阻塞当前线程
            LockSupport.park();
            // 线程唤醒后移出阻塞队列，重新争抢资源
            waiter.remove(Thread.currentThread());
        }
    }

    /**
     * 解锁
     */
    @Override
    public void unlock() {
        // 将原子对象内部的线程替换成null -> 原子对象内部的线程就是当前线程
        if (owner.compareAndSet(Thread.currentThread(), null)) {
            // 如果释放成功
            // 唤醒阻塞队列中所有的线程
            for (Thread thread : waiter) {
                LockSupport.unpark(thread);
            }
        }
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {

    }

    @Override
    public boolean tryLock() {
        return false;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return false;
    }

    @Override
    public Condition newCondition() {
        return null;
    }
}
